function MyPromise(excutor) {

    const instance = this   // 保存this, 此时this指向其实例对象

    /* 
        [[PromiseState]]用于储存Promise实例的状态
        Promise一共有三种状态: pending fulfilled rejected
        且状态只能从:
            pending => fulfilled
            pending => rejected
    */
    instance["[[PromiseState]]"] = "pending"

    /* 
        [[PromiseState]]用于储存Promise实例的值
        初始值为undefined
    */
    instance["[[PromiseResult]]"] = undefined


    /* 
        __callbacks用于保存当Promise实例是:
            先指定then回调再改变状态时
        的then回调，让其在等到状态改变完后执行
    */
    instance["__callbacks"] = []


    // 改变Promise实例状态为成功
    function __resolve(PromiseResult) {
        if (instance["[[PromiseState]]"] !== "pending") return  // 状态只能改变一次
        instance["[[PromiseState]]"] = "fulfilled"
        instance["[[PromiseResult]]"] = PromiseResult

        // 当前时先指定回调后改变状态的情况是
        if (instance["__callbacks"].length > 0) {
            // 注意：promise属于微任务，使用宏任务模拟
            setTimeout(
                () => {
                    instance["__callbacks"].forEach(
                        ({ onResolved }) => {
                            onResolved(PromiseResult)
                        }
                    )
                }
            )
        }
    }
    
    // 改变Promise实例状态为失败
    function __reject(PromiseResult) {
        if (instance["[[PromiseState]]"] !== "pending") return  // 状态只能改变一次
        instance["[[PromiseState]]"] = "rejected"
        instance["[[PromiseResult]]"] = PromiseResult

        // throw `(in my promise) ${PromiseResult}`

        // 当前时先指定回调后改变状态的情况是
        if (instance["__callbacks"].length > 0) {
            // 注意：promise属于微任务，使用宏任务模拟
            setTimeout(
                () => {
                    instance["__callbacks"].forEach(
                        ({ onRejected }) => {
                            onRejected(PromiseResult)
                        }
                    )
                }
            )
        }
    }


    try {
        /* 
            excutor有三种情况:
                1. 调用__resolve(), Promise实例状态改变为fulfilled, 值为传入__resolve的实参
                2. 调用__reject(), Promise实例状态改变为rejected, 值为传入__reject的实参
                3. 在excutor中使用throw关键字抛出对象或错误, Promise实例状态改变为rejected, 值为被抛出的对象
        */
        excutor(__resolve, __reject)   // 同步执行excutor
    } catch (throwVal) {
        __reject(throwVal)
    }
}

// 创建thenable: thenable是指那些类似Promise的功能且有then方法的对象, 可以认为thenable是Promise的鸭子类型
MyPromise.prototype.then = function (onResolved, onRejected) {

    const instance = this
    
    if (onResolved || onRejected) {

        // 如果向then传入的不是一个回调函数, 则忽略传入的实参，改为自动创建一个函数
        if (!onResolved || Object.prototype.toString.call(onResolved) !== "[object Function]") {
            onResolved = v => v     // return v使得能够在下一个then中接收到因为上一个then没有指定正确回调而没有接收到的PromiseResult
        }

        /* 
            与上面作用一直, 并且还实现了异常穿透
            
            异常穿透的原理:
                在当前没有指定onRejected的情况下，自动创建一个函数作为onRejected
                并且这个函数需要满足：
                    1. 能够将值传递到下一次then中
                    2. 使得本次then返回的promise的状态为rejected，即：下一次then中会执行onRejected
        */
        if (!onRejected || Object.prototype.toString.call(onRejected) !== "[object Function]") {
            onRejected = r => { throw r }
        }

            // then方法返回值是一个promise, 使其能够进行链式调用
        return new MyPromise(
            (resolve, reject) => {
                // 由于then属于微任务，然而无法通过API去创建微任务，只能使用宏任务去代替，总之不能同步执行
                setTimeout(
                    () => {
                        /* 
                            执行then中的两个回调会对then所返回的promise状态的影响：
                                1. 返回一个非Promise类型的值，返回的promise状态为fulfilled，值为该回调的返回值
                                2. 在回调内部使用throw关键字抛出错误，返回的promise状态为rejected，值为throw出的值
                                3. 返回的是一个promise，则当前then返回的promise状态和值为该回调返回的promise的状态和值
                        */
                        if (instance["[[PromiseState]]"] === "fulfilled") {     // 当先改变状态后指定回调--------成功状态执行onResolved时
                            try {
                                let returnValue = onResolved(instance["[[PromiseResult]]"])     // 向回调注入实参
        
                                if (returnValue instanceof MyPromise) {     // 情况3
                                    /* 
                                        此时returnValue由于是一个thenable，所以其必然能调用then方法
                                        那么此时这个新返回的promise的状态和值就交给returnValue的then自动处理即可
                                    */
                                    // returnValue.then(
                                    //     v => resolve(v),
                                    //     e => reject(e)
                                    // )
        
                                    /* 
                                        由于then中的回调会自动 向回调注入实参, 所以有简写方式
                                        简写与上面的区别:
                                            上面的:
                                                function onResolved (v) {
                                                    resolve(v)
                                                }
                                                onResolved(v)
                                            简写：
                                                let onResolved = function resolve (v) {}
                                                onResolved(v)
                                    */
                                    returnValue.then(resolve, reject)
        
                                }else {     // 情况1
                                    resolve(returnValue)
                                }
                            } catch (throwVal) {    // 情况2
                                reject(throwVal)
                            }
                        }else if (instance["[[PromiseState]]"] === "rejected") {    // 当先改变状态后指定回调--------失败状态执行onRejected时
                            try {
                                let returnValue = onRejected(instance["[[PromiseResult]]"])
                                if (returnValue instanceof MyPromise) {     // 情况3
                                    returnValue.then(resolve, reject)
                                }else {     // 情况1
                                    resolve(returnValue)
                                }
                            } catch (throwVal) {    // 情况2
                                reject(throwVal)
                            }
                        }else {     // 当先指定回调后改变状态时
                            /* 
                                对于这种情况需要先将回调保存在一个数组中, 延迟到当状态改变时执行
                                使用数组的原因是: 使用者可能多次为同一promise使用then指定多组回调，且promise会都执行这些回调
        
                                **注意**  这个新返回的promise的值需要在若干时间后改变状态时传入, 
                                        即需要被传入实参，所以不能简单传入回调函数，而是需要被一个函数包装一下
                            */
                            instance["__callbacks"].push(
                                {
                                    onResolved: function(PromiseResult) {
                                        try {
                                            let returnValue = onResolved(PromiseResult)
                                            if (returnValue instanceof MyPromise) {     // 情况3
                                                returnValue.then(resolve, reject)
                                            }else {     // 情况1
                                                resolve(returnValue)
                                            }
                                        } catch (throwVal) {    // 情况2
                                            reject(throwVal)
                                        }
                                    },
                                    onRejected: function(PromiseResult) {
                                        try {
                                            let returnValue = onRejected(PromiseResult)
                                            if (returnValue instanceof MyPromise) {     // 情况3
                                                returnValue.then(resolve, reject)
                                            }else {     // 情况1
                                                resolve(returnValue)
                                            }
                                        } catch (throwVal) {    // 情况2
                                            reject(throwVal)
                                        }
                                        reject(PromiseResult)
                                    }
                                }
                            )
                        }
                    }
                )
            }
        )
    }else {
        // 如果只是单纯调用then方法而不是指定任何一个回调, 则返回实例
        return this
    }
}



// 可以在这统一处理rejected
MyPromise.prototype.catch = function (onRejected) {
    const instance = this
    return instance.then(null, onRejected)
}



/* 
    **注意** onFinally不需要任何的实参

    Promise.prototype.finally()有以下几种情况:
        1. 当onFinally没有返回值(默认 return undefined)时, 返回的Promise状态和值与链式调用前一段返回的Promise的状态和值相同
        2. 当onFinally有返回值时
            2-1. 返回值是一个非promise类型的值, 返回的Promise状态和值与链式调用前一段返回的Promise的状态和值相同(与情况1一致)
            2-2. 返回值是一个promise类型的值且状态为fulfilled, 返回的Promise状态和值与链式调用前一段返回的Promise的状态和值相同(与情况1一致)
            2-3. 返回值是一个promise类型的值且状态为rejected, 返回的Promise状态为rejected, 值为onFinally的返回值
            2-4. 如果在onFinally内使用throw关键字抛出对象，则与情况2-3相同
*/
MyPromise.prototype.finally = function (onFinally) {
    const instance = this
    return instance.then(   // 保证finally一定是最后执行
        // 由于onFinally不需要任何的实参，所以使用一层函数包裹，防止then自动将实参注入onFinally
        () => {
            try {
                let returnValue = onFinally()
                if (Object.prototype.toString.call(returnValue) === "[object Undefined]") {     // 情况1
                    return instance
                }else {
                    if (returnValue instanceof MyPromise) {
                        if (returnValue["[[PromiseState]]"] === "fulfilled"){     // 情况2-2
                            return instance
                        }else {     // 情况2-3
                            return returnValue
                        }
                    }else {     // 情况2-1
                        return instance
                    }
                }
            } catch (throwVal) {    // 情况2-4
                return throwVal
            }
        },
        () => {
            // 是上述所有情况的简写
            try {
                let returnValue = onFinally()
                if (returnValue instanceof MyPromise && returnValue["[[PromiseState]]"] === "rejected") {
                    return returnValue
                }else {
                    return instance
                }
            } catch (throwVal) {    // 情况2-4
                return throwVal
            }
        }
    )
}




/* 
    最开始分为两种情况:
        1. 传入了val
            1-1. 该值是一个promise，则新返回的这个promise的状态和值都由该promise决定
            1-2. 该值是一个普通对象，则新返回的这个promise的状态为fulfilled，值为该普通对象
        2. 没传val: 返回的promise状态为fulfilled，值为undefined
*/
MyPromise.resolve = function (val) {
    return new MyPromise(
        (resolve, reject) => {
            if (val) {
                if (val instanceof MyPromise) {
                    val.then(resolve, reject)
                }else {
                    resolve(val)
                }
            }else {
                resolve()
            }
        }
    )
}



/* 
    最开始分为两种情况:
        1. 传入了val
            1-1. 该值是一个promise,无论该promise的状态是成功还是失败，
                则新返回的这个promise的状态都为rejected，值为该promise
            1-2. 该值是一个普通对象，则新返回的这个promise的状态为rejected，值为该普通对象
        2. 没传val: 返回的promise状态为rejected，值为undefined
*/
MyPromise.reject = function (val) {
    return new MyPromise(
        (resolve, reject) => {
            if (val) {
                if (val instanceof MyPromise) {
                    reject(val)
                }else {
                    reject(val)
                }
            }else {
                reject()
            }
        }
    )
}



/* 
    传入一个由一个或多个Promise组成的数组或其他可迭代对象
    所有promise都成功时，all返回的promise为成功，值为所有promise结果组成的数组  **注意：无论请求的响应顺序是什么,数组的顺序总是对应实参传入时的顺序**
    只要有promise失败时，all立即返回promise且状态为失败，值为该失败promise的PromiseResult
*/
MyPromise.all = function (myPromises) {
    if (Object.prototype.toString.call(myPromises[Symbol.iterator]) === "[object Function]") {
        return new MyPromise(
            (resolve, reject) => {
                // 使用spread运算符将其变为数组，方便得到length和使用forEach
                myPromises = [...myPromises]
                let PromiseResult = []  // 保存所有promise成功是时候的数组
                myPromises.forEach(
                    (myPromise, index) => {
                        myPromise.then(
                            r => {
                                PromiseResult[index] = r
                                if (index === myPromises.length - 1) {
                                    // 当最后一个元素返回结果时, all返回所有成功promise的结果
                                    resolve(PromiseResult)
                                }
                            },
                            e => {
                                reject(e)
                            }
                        )
                    }
                )
            }
        )
    }else {
        // 对于非可迭代对象, 将报错
        throw new TypeError("传入的第一个实参不是一个可迭代(iterable)对象")
    }
}



/* 
    传入一个由一个或多个Promise组成的数组或其他可迭代对象
    race返回的promise的状态和值由最先响应的promise决定
*/
MyPromise.race = function (myPromises) {
    if (Object.prototype.toString.call(myPromises[Symbol.iterator]) === "[object Function]") {
        return new MyPromise(
            (resolve, reject) => {
                // 使用spread运算符将其变为数组，方便得到length和使用forEach
                myPromises = [...myPromises]
                myPromises.forEach(
                    myPromise => {
                        myPromise.then(
                            r => {
                                resolve(r)
                            },
                            e => {
                                reject(e)
                            }
                        )
                    }
                )
            }
        )
    }else {
        // 对于非可迭代对象, 将报错
        throw new TypeError("传入的第一个实参不是一个可迭代(iterable)对象")
    }
}


/* 
    传入一个由一个或多个Promise组成的数组或其他可迭代对象
    any返回的promise的状态和值由最先成功的promise决定
    如果所有promise都失败，则报错AggregateError: All promises were rejected

    对比all和any:
    前者有一个失败就失败然后返回失败的结果，所有成功则返回所有成功的结果
    后者一个成功就成功然后返回成功的结果，所有失败就报错
*/
MyPromise.any = function (myPromises) {
    if (Object.prototype.toString.call(myPromises[Symbol.iterator]) === "[object Function]") {
        return new MyPromise(
            (resolve, reject) => {
                // 使用spread运算符将其变为数组，方便得到length和使用forEach
                myPromises = [...myPromises]
                let PromiseResult = []  // 保存所有promise成功是时候的数组
                myPromises.forEach(
                    (myPromise, index) => {
                        myPromise.then(
                            r => {
                                resolve(r)
                            },
                            e => {
                                if (index === myPromises.length - 1) {
                                    throw new Error("AggregateError: All promises were rejected")
                                }
                            }
                        )
                    }
                )
            }
        )
    }else {
        // 对于非可迭代对象, 将报错
        throw new TypeError("传入的第一个实参不是一个可迭代(iterable)对象")
    }
}


/* 
    传入一个由一个或多个Promise组成的数组或其他可迭代对象
    allSettled返回的promise的状态一定是成功的
    值是一个数组, 数组中每个对象对应实参给定的Promise的状态和值(顺序与传入的Promise数组一致, 而不会根据Promise的响应时间改变)
    [
        {status: 'fulfilled', value: 1},
        {status: 'rejected', reason: 2},
        {status: 'fulfilled', value: 3}
    ]
*/
MyPromise.allSettled = function (myPromises) {
    if (Object.prototype.toString.call(myPromises[Symbol.iterator]) === "[object Function]") {
        return new MyPromise(
            resolve => {
                // 使用spread运算符将其变为数组，方便得到length和使用forEach
                myPromises = [...myPromises]
                let PromiseResult = []  // 保存所有promise成功是时候的数组
                myPromises.forEach(
                    (myPromise, index) => {
                        myPromise.then(
                            r => {
                                PromiseResult[index] = {
                                    status: "fulfilled",
                                    value: r
                                }
                                if (index === myPromises.length - 1) {
                                    // 当最后一个元素返回结果时, 返回allSettled
                                    resolve(PromiseResult)
                                }
                            },
                            e => {
                                PromiseResult[index] = {
                                    status: "rejected",
                                    reason: e
                                }
                                if (index === myPromises.length - 1) {
                                    // 当最后一个元素返回结果时, 返回allSettled
                                    resolve(PromiseResult)
                                }
                            }
                        )
                    }
                )
            }
        )
    }else {
        // 对于非可迭代对象, 将报错
        throw new TypeError("传入的第一个实参不是一个可迭代(iterable)对象")
    }
}
